package com.task.scheduler.queue;

import com.task.scheduler.config.TaskSchedulerProperties;
import com.task.scheduler.enums.TaskStatus;
import com.task.scheduler.executor.TaskExecutor;
import com.task.scheduler.model.GenericTask;
import com.task.scheduler.persistence.entity.TaskEntity;
import com.task.scheduler.persistence.entity.TaskExecutionEntity;
import com.task.scheduler.persistence.repository.TaskExecutionRepository;
import com.task.scheduler.persistence.repository.TaskRepository;
import com.task.scheduler.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiConsumer;

@Service
@Slf4j
public class LocalTaskQueueService implements TaskService {

    private final Map<String, TaskExecutor> executorMap = new HashMap<>();
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private final Set<String> canceledTasks = new HashSet<>();

    @Autowired
    private TaskSchedulerProperties taskSchedulerProperties; // ✅ 修改为统一配置类
    @Autowired
    private TaskExecutionRepository taskExecutionRepository;
    @Autowired
    private TaskRepository taskRepository;



    public LocalTaskQueueService(List<TaskExecutor> taskExecutors) {

        for (TaskExecutor executor : taskExecutors) {
            Class<? extends TaskExecutor> clazz = executor.getClass();
            if (clazz.isAnnotationPresent(com.task.scheduler.executor.TaskType.class)) {
                com.task.scheduler.executor.TaskType annotation = clazz.getAnnotation(com.task.scheduler.executor.TaskType.class);
                for (String type : annotation.value()) {
                    executorMap.put(type, executor);
                }
            }
        }
    }


    @Override
    public void submit(GenericTask task) {
        executorService.submit(() -> process(task));
    }

    @Override
    public void cancel(String taskId) {
        canceledTasks.add(taskId);
        log.info("任务 [{}] 已标记为取消", taskId);
    }

    private void process(GenericTask task) {
        if (canceledTasks.contains(task.getTaskId())) {
            log.info("任务 [{}] 已被取消，跳过执行", task.getTaskId());
            return;
        }

        TaskExecutor matchedExecutor = task.getExecutor(); // 优先使用自定义执行器
        if (matchedExecutor == null) {
            log.warn("⚠️ 未找到匹配执行器，请检查 taskType 或注册自定义 TaskExecutor");
            return; // 不再尝试自动匹配，直接跳过执行
        }

        String result = null;
        TaskStatus status = TaskStatus.FAILED;

        try {
            result = matchedExecutor.execute(task);
            status = TaskStatus.SUCCESS;

            BiConsumer<GenericTask, String> onSuccess = task.getOnSuccess();
            if (onSuccess != null) {
                onSuccess.accept(task, result);
            }

        } catch (Exception e) {
            task.setLastErrorMessage(e.getMessage());  // 记录失败原因
            log.error("任务 [{}] 执行失败: {}", task.getTaskId(), e.getMessage(), e);  // 输出完整堆栈
            BiConsumer<GenericTask, Exception> onFailure = task.getOnFailure();
            if (onFailure != null) {
                onFailure.accept(task, e);
            }

            if (task.getRetryCount() < task.getMaxRetry()) {
                task.setRetryCount(task.getRetryCount() + 1);
                submit(task); // 本地重新入队
            }
        }

        // ✅ 持久化逻辑开始
        if (taskSchedulerProperties.getPersistence().isEnabled()) {
            TaskEntity taskEntity = new TaskEntity();
            taskEntity.setId(task.getTaskId());
            taskEntity.setTaskType(task.getTaskType());
            taskEntity.setJsonParams(task.getJsonParams());
            taskEntity.setMaxRetry(task.getMaxRetry());
            taskEntity.setDelaySeconds(task.getDelaySeconds());
            taskEntity.setExecutionMode(task.getExecutionMode());

            TaskExecutionEntity executionEntity = new TaskExecutionEntity();
            executionEntity.setTaskId(task.getTaskId());
            executionEntity.setRetryCount(task.getRetryCount());
            executionEntity.setStatus(status);
            executionEntity.setResult(result);
            executionEntity.setErrorMessage(task.getLastErrorMessage());

            taskRepository.save(taskEntity);
            taskExecutionRepository.save(executionEntity);

            // 更新 latest_execution_id
            taskEntity.setLatestExecutionId(executionEntity.getId());
            taskRepository.save(taskEntity);
        }
        // ✅ 持久化逻辑结束

    }
}
